﻿using System;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace StrategyGame
{
	/// <summary>
	/// Utility class with functions for rendering and laying out text
	/// </summary>
	class TextUtils
	{
		/// <summary>
		/// Draw text with a dropshadow (much more readable against a multicolored background)
		/// </summary>
		/// <param name="sprites">SpriteBatch object to draw with</param>
		/// <param name="font">SpriteFont to render</param>
		/// <param name="text">The string to be rendered</param>
		/// <param name="pos">Screen position of the main text (not the shadow)</param>
		/// <param name="text_color">Color of the main text</param>
		/// <param name="shadow_color">Color of the dropshadow</param>
		/// <param name="shadow_distance">Distance in pixels that the dropshadow is offset by</param>
		public static void DrawWithDropShadow(SpriteBatch sprites, SpriteFont font, string text, Vector2 pos, Color text_color, Color shadow_color, int shadow_distance)
		{
			Vector2 shadow_pos = new Vector2();
			shadow_pos.X = pos.X + shadow_distance;
			shadow_pos.Y = pos.Y + shadow_distance;

			sprites.DrawString(font, text, shadow_pos, shadow_color);
			sprites.DrawString(font, text, pos, text_color);
		}

		public enum VerticalAlignment
        {
            Top,
            Middle,
            Bottom
        }   

        public enum HorizontalAlignment
        {
            Left,
            Middle,
            Right
        }

        public static Vector2 GetPositionForAlignedText(SpriteFont font, string text, Rectangle target_rect, HorizontalAlignment h_align, VerticalAlignment v_align)
        {
            Vector2 result = new Vector2();

            Vector2 text_size = font.MeasureString(text);

            switch (h_align)
            {
                case HorizontalAlignment.Left:
                    result.X = target_rect.X;
                    break;
                case HorizontalAlignment.Middle:
                    result.X = target_rect.Left + (target_rect.Width / 2 - (int)text_size.X / 2);
                    break;
                case HorizontalAlignment.Right:
                    result.X = target_rect.Right - (int)text_size.X;
                    break;
            }

            switch (v_align)
            {
                case VerticalAlignment.Top:
                    result.Y = target_rect.Y;
                    break;
                case VerticalAlignment.Middle:
                    result.Y = target_rect.Top + (target_rect.Height / 2 - (int)text_size.Y / 2);
                    break;
                case VerticalAlignment.Bottom:
                    result.Y = target_rect.Bottom - (int)text_size.Y;
                    break;
            }

            return result;
        }

        //todo: break this down so it just returns an array of positions, allowing caching of positions so it's not recalculated every draw
        //also makes it easier to do dropshadows with this
        public static void DrawMultipleAlignedLines(SpriteBatch sprites, SpriteFont font, Color color, string[] lines, Rectangle target_rect, HorizontalAlignment h_align, VerticalAlignment v_align)
        {
            Vector2[] line_sizes = new Vector2[lines.Length];

            for (int line_it = 0;
                line_it < lines.Length;
                ++line_it)
            {
                Vector2 this_line_size;

                if (lines[line_it] == String.Empty)
                    this_line_size = font.MeasureString("|");
                else
                    this_line_size = font.MeasureString(lines[line_it]);

                line_sizes[line_it] = this_line_size;
            }

            float total_height = 0;
            float longest_width = 0;
            foreach (Vector2 each_line_size in line_sizes)
            {
                total_height += each_line_size.Y;
                longest_width = Math.Max(longest_width, each_line_size.X);
            }

            float currentline_y = 0;
            switch (v_align)
            {
                case VerticalAlignment.Top:
                    currentline_y = target_rect.Y;
                    break;
                case VerticalAlignment.Middle:
                    currentline_y = target_rect.Y + (target_rect.Height/2 - total_height/2);
                    break;
                case VerticalAlignment.Bottom:
                    currentline_y = target_rect.Bottom - total_height;
                    break;
            }

            for (int line_it = 0;
                line_it < lines.Length;
                ++line_it)
            {
                Rectangle line_rect = new Rectangle();
                line_rect.Width = (int)longest_width;
                line_rect.Height = (int)line_sizes[line_it].Y;
                line_rect.Y = (int)currentline_y;
                
                switch (h_align)
                {
                    case HorizontalAlignment.Left:
                        line_rect.X = target_rect.X;
                        break;
                    case HorizontalAlignment.Middle:
                        line_rect.X = target_rect.X + (int)(target_rect.Width/2 - longest_width/2);
                        break;
                    case HorizontalAlignment.Right:
                        line_rect.X = target_rect.Right - (int)longest_width;
                        break;
                }

                Vector2 line_pos = GetPositionForAlignedText(font, lines[line_it], line_rect, h_align, VerticalAlignment.Bottom);

                sprites.DrawString(font, lines[line_it], line_pos, color);

                currentline_y += line_rect.Height;
            }
        }
	}
}
